home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / code / eval.lisp < prev    next >
Encoding:
Text File  |  1992-05-30  |  15.2 KB  |  448 lines

  1. ;;; -*- Log: code.log; Package: Lisp -*-
  2. ;;;
  3. ;;; **********************************************************************
  4. ;;; This code was written as part of the CMU Common Lisp project at
  5. ;;; Carnegie Mellon University, and has been placed in the public domain.
  6. ;;; If you want to use this code or any part of CMU Common Lisp, please contact
  7. ;;; Scott Fahlman or slisp-group@cs.cmu.edu.
  8. ;;;
  9. (ext:file-comment
  10.   "$Header: eval.lisp,v 1.18 92/05/15 20:30:07 wlott Exp $")
  11. ;;;
  12. ;;; **********************************************************************
  13. ;;;
  14. (in-package "LISP")
  15. (export '(eval constantp quote proclaim
  16.       eval-when progn prog1 prog2 let let*
  17.       do do* dotimes dolist progv and or cond if the
  18.       macro-function special-form-p *macroexpand-hook*
  19.       macroexpand-1 macroexpand block return-from
  20.       compiler-macroexpand compiler-macroexpand-1
  21.       compiler-macro-function
  22.       return function setq psetq apply funcall
  23.       compiler-let progv flet labels macrolet
  24.       mapcar maplist mapc mapl mapcan mapcon
  25.       tagbody prog prog* go 
  26.       values multiple-values-limit
  27.       values-list multiple-value-list multiple-value-call
  28.       multiple-value-prog1 multiple-value-bind multiple-value-setq
  29.       catch unwind-protect throw defun
  30.       lambda-list-keywords call-arguments-limit lambda-parameters-limit
  31.       function-lambda-expression
  32.           ;;
  33.           ;; Declaration symbols referenced in the cold load.
  34.           declare special 
  35.       ;;
  36.       ;; Magical markers...
  37.       lambda &optional &rest &key &aux &body &whole
  38.       &allow-other-keys &environment))
  39.  
  40. #| Not implemented:
  41. *evalhook* *applyhook* evalhook applyhook 
  42. |#
  43.  
  44. (export '(eval::interpreted-function-p
  45.       eval::interpreted-function-lambda-expression)
  46.     "EVAL")
  47. (import '(eval::*eval-stack-top*))
  48.  
  49. (in-package "SYSTEM")
  50. (export '(parse-body find-if-in-closure))
  51.  
  52. (in-package "EXTENSIONS")
  53. (export '(*top-level-auto-declare*))
  54.  
  55. (in-package "KERNEL")
  56. (export '(invoke-macroexpand-hook))
  57.  
  58. (in-package "LISP")
  59.  
  60.  
  61. (defconstant lambda-list-keywords
  62.   '(&optional &rest &key &aux &body &whole &allow-other-keys &environment)
  63.   "Keywords that you can put in a lambda-list, supposing you should want
  64.   to do such a thing.")
  65.  
  66. (defconstant call-arguments-limit most-positive-fixnum
  67.   "The exclusive upper bound on the number of arguments which may be passed
  68.   to a function, including rest args.")
  69.  
  70. (defconstant lambda-parameters-limit most-positive-fixnum
  71.   "The exclusive upper bound on the number of parameters which may be specifed
  72.   in a given lambda list.  This is actually the limit on required and optional
  73.   parameters.  With &key and &aux you can get more.")
  74.  
  75. (defconstant multiple-values-limit most-positive-fixnum
  76.   "The exclusive upper bound on the number of multiple-values that you can
  77.   have.")
  78.  
  79.  
  80.  
  81. ;;;; EVAL and friends.
  82.  
  83. ;;;
  84. ;;; This flag is used by EVAL-WHEN to keep track of when code has already been
  85. ;;; evaluated so that it can avoid multiple evaluation of nested EVAL-WHEN
  86. ;;; (COMPILE)s.
  87. (defvar *already-evaled-this* nil)
  88.  
  89. ;;;
  90. ;;; This needs to be initialized in the cold load, since the top-level catcher
  91. ;;; will always restore the initial value.
  92. (defvar *eval-stack-top* 0)
  93.  
  94. (declaim (type (member :warn t nil) *top-level-auto-declare*))
  95.  
  96. (defvar *top-level-auto-declare* :warn
  97.   "This variable controls whether assignments to unknown variables at top-level
  98.    (or in any other call to EVAL of SETQ) will implicitly declare the variable
  99.    SPECIAL.  These values are meaningful:
  100.      :WARN  -- Print a warning, but declare the variable special (the default.)
  101.       T     -- Quietly declare the variable special.
  102.       NIL   -- Never declare the variable, giving warnings on each use.")
  103.   
  104.  
  105. ;;; EVAL  --  Public
  106. ;;;
  107. ;;;    Pick off a few easy cases, and call INTERNAL-EVAL for the rest.  If
  108. ;;; *ALREADY-EVALED-THIS* is true, then we bind it to NIL before doing a call
  109. ;;; so that the effect is confined to the lexical scope of the EVAL-WHEN.
  110. ;;;
  111. (defun eval (original-exp)
  112.   "Evaluates its single arg in a null lexical environment, returns the
  113.   result or results."
  114.   (declare (optimize (safety 1)))
  115.   (let ((exp (macroexpand original-exp)))
  116.     (typecase exp
  117.       (symbol
  118.        (ecase (info variable kind exp)
  119.      (:constant
  120.       (values (info variable constant-value exp)))
  121.      ((:special :global)
  122.       (symbol-value exp))
  123.      (:alien
  124.       (eval:internal-eval original-exp))))
  125.       (list
  126.        (let ((name (first exp))
  127.          (args (1- (length exp))))
  128.      (case name
  129.        (function
  130.         (unless (= args 1)
  131.           (error "Wrong number of args to FUNCTION:~% ~S." exp))
  132.         (let ((name (second exp)))
  133.           (if (or (atom name)
  134.               (and (consp name)
  135.                (eq (car name) 'setf)))
  136.           (fdefinition name)
  137.           (eval:make-interpreted-function name))))
  138.        (quote
  139.         (unless (= args 1)
  140.           (error "Wrong number of args to QUOTE:~% ~S." exp))
  141.         (second exp))
  142.        (setq
  143.         (unless (evenp args)
  144.           (error "Odd number of args to SETQ:~% ~S." exp))
  145.         (unless (zerop args)
  146.           (do ((name (cdr exp) (cddr name)))
  147.           ((null name)
  148.            (do ((args (cdr exp) (cddr args)))
  149.                ((null (cddr args))
  150.             ;; We duplicate the call to SET so that the correct
  151.             ;; value gets returned.
  152.             (set (first args) (eval (second args))))
  153.              (set (first args) (eval (second args)))))
  154.         (let ((symbol (first name)))
  155.           (case (info variable kind symbol)
  156.             (:special)
  157.             (:global
  158.              (case *top-level-auto-declare*
  159.                (:warn
  160.             (warn "Declaring ~S special." symbol))
  161.                ((t))
  162.                ((nil)
  163.             (return (eval:internal-eval original-exp))))
  164.              (proclaim `(special ,symbol)))
  165.             (t
  166.              (return (eval:internal-eval original-exp))))))))
  167.        ((progn)
  168.         (when (> args 0)
  169.           (dolist (x (butlast (rest exp)) (eval (car (last exp))))
  170.         (eval x))))
  171.        ((eval-when)
  172.         (if (and (> args 0) (member 'eval (second exp)))
  173.         (when (> args 1)
  174.           (dolist (x (butlast (cddr exp)) (eval (car (last exp))))
  175.             (eval x)))
  176.         (eval:internal-eval original-exp)))
  177.        (t
  178.         (if (and (symbolp name)
  179.              (eq (info function kind name) :function))
  180.         (collect ((args))
  181.           (dolist (arg (rest exp))
  182.             (args (eval arg)))
  183.           (if *already-evaled-this*
  184.               (let ((*already-evaled-this* nil))
  185.             (apply (symbol-function name) (args)))
  186.               (apply (symbol-function name) (args))))
  187.         (eval:internal-eval original-exp))))))
  188.       (t
  189.        exp))))
  190.  
  191.  
  192. ;;; INTERPRETED-FUNCTION-P  --  Interface
  193. ;;;
  194. ;;;    This is defined here so that the printer &c can call it before the full
  195. ;;; interpreter is loaded.
  196. ;;;
  197. (defun eval:interpreted-function-p (x)
  198.   (and (functionp x)
  199.        (= (get-type x) vm:closure-header-type)
  200.        (fboundp 'eval::leaf-value)
  201.        (let ((code-component (di::function-code-header (%closure-function x))))
  202.      (or (eq (di::function-code-header #'eval::leaf-value)
  203.          code-component)
  204.          (eq (di::function-code-header #'eval:make-interpreted-function)
  205.          code-component)))))
  206.  
  207.  
  208. ;;; FUNCTION-LAMBDA-EXPRESSION  --  Public
  209. ;;;
  210. ;;;    If interpreted, use the interpreter interface.  Otherwise, see if it was
  211. ;;; compiled with COMPILE.  If that fails, check for an inline expansion.
  212. ;;;
  213. (defun function-lambda-expression (fun)
  214.   "Given a function, return three values:
  215.    1] A lambda expression that could be used to define the function, or NIL if
  216.       the definition isn't available.
  217.    2] NIL if the function was definitely defined in a null lexical environment,
  218.       and T otherwise.
  219.    3] Some object that \"names\" the function.  Although this is allowed to be
  220.       any object, CMU CL always returns a valid function name or a string."
  221.   (declare (type function fun))
  222.   (if (eval:interpreted-function-p fun)
  223.       (eval:interpreted-function-lambda-expression fun)
  224.       (let* ((fun (%primitive c::function-self fun))
  225.          (name (%primitive c::function-name fun))
  226.          (code (di::function-code-header fun))
  227.          (info (di::code-debug-info code)))
  228.     (if info
  229.         (let ((source (first (c::compiled-debug-info-source info))))
  230.           (cond ((and (eq (c::debug-source-from source) :lisp)
  231.               (eq (c::debug-source-info source) fun))
  232.              (values (second (svref (c::debug-source-name source) 0))
  233.                  nil name))
  234.             ((stringp name)
  235.              (values nil t name))
  236.             (t
  237.              (let ((exp (info function inline-expansion name)))
  238.                (if exp
  239.                (values exp nil name)
  240.                (values nil t name))))))
  241.         (values nil t name)))))
  242.  
  243.  
  244. ;;; FIND-IF-IN-CLOSURE  --  Interface
  245. ;;;
  246. ;;;    Like FIND-IF, only we do it on a compiled closure's environment.
  247. ;;;
  248. (defun find-if-in-closure (test fun)
  249.   (dotimes (index (1- (get-closure-length fun)))
  250.     (let ((elt (%closure-index-ref fun index)))
  251.       (when (funcall test elt)
  252.     (return elt)))))
  253.  
  254.  
  255. ;;;; Syntactic environment access:
  256.  
  257. (defun special-form-p (symbol)
  258.   "If the symbol globally names a special form, returns the definition in a
  259.   mysterious internal format (a FEXPR), else returns NIL."
  260.   (declare (symbol symbol))
  261.   (eq (info function kind symbol) :special-form))
  262.  
  263. (defvar *macroexpand-hook* 'funcall
  264.   "The value of this variable must be a function that can take three
  265.   arguments, a macro expander function, the macro form to be expanded,
  266.   and the lexical environment to expand in.  The function should
  267.   return the expanded form.  This function is called by MACROEXPAND-1
  268.   whenever a runtime expansion is needed.  Initially this is set to
  269.   FUNCALL.")
  270.  
  271. ;;; INVOKE-MACROEXPAND-HOOK -- public.
  272. ;;;
  273. ;;; The X3J13 cleanup FUNCTION-TYPE:X3J13-MARCH-88 specifies that:
  274. ;;; 
  275. ;;; "7. Clarify that the value of *MACROEXPAND-HOOK* is first coerced to a
  276. ;;;     function before being called as the expansion interface hook by
  277. ;;;     MACROEXPAND-1."
  278. ;;;
  279. ;;; This is a handy utility function that does just such a coercion.  It also
  280. ;;; stores the result back in *macroexpand-hook* so we don't have to coerce
  281. ;;; it again.
  282. ;;; 
  283. (defun invoke-macroexpand-hook (fun form env)
  284.   "Invoke *MACROEXPAND-HOOK* on FUN, FORM, and ENV after coercing it to
  285.    a function."
  286.   (unless (functionp *macroexpand-hook*)
  287.     (setf *macroexpand-hook*
  288.       (coerce *macroexpand-hook* 'function)))
  289.   (funcall *macroexpand-hook* fun form env))
  290.  
  291. (defun macro-function (symbol &optional env)
  292.   "If SYMBOL names a macro in ENV, returns the expansion function,
  293.    else returns NIL.  If ENV is unspecified or NIL, use the global
  294.    environment only."
  295.   (declare (symbol symbol))
  296.   (let* ((fenv (when env (c::lexenv-functions env)))
  297.      (local-def (cdr (assoc symbol fenv))))
  298.     (cond (local-def
  299.        (if (and (consp local-def) (eq (car local-def) 'MACRO))
  300.            (cdr local-def)
  301.            nil))
  302.       ((eq (info function kind symbol) :macro)
  303.        (values (info function macro-function symbol)))
  304.       (t
  305.        nil))))
  306.  
  307. (defun (setf macro-function) (function symbol)
  308.   (declare (symbol symbol) (type function function))
  309.  
  310.   (when (eq (info function kind symbol) :special-form)
  311.     (error "~S names a special form." symbol))
  312.  
  313.   (setf (info function kind symbol) :macro)
  314.   (setf (info function macro-function symbol) function)
  315.   (setf (symbol-function symbol)
  316.     #'(lambda (&rest args) (declare (ignore args))
  317.         (error "Cannot funcall macro functions.")))
  318.   function)
  319.  
  320. ;;; Macroexpand-1  --  Public
  321. ;;;
  322. ;;;    The Env is a LEXENV or NIL (the null environment.)
  323. ;;;
  324. (defun macroexpand-1 (form &optional env)
  325.   "If form is a macro (or symbol macro), expands it once.  Returns two values,
  326.    the expanded form and a T-or-NIL flag indicating whether the form was, in
  327.    fact, a macro.  Env is the lexical environment to expand in, which defaults
  328.    to the null environment."
  329.   (cond ((and (consp form) (symbolp (car form)))
  330.      (let ((def (macro-function (car form) env)))
  331.        (if def
  332.            (values (invoke-macroexpand-hook def form env) t)
  333.            (values form nil))))
  334.     ((symbolp form)
  335.      (let* ((venv (when env (c::lexenv-variables env)))
  336.         (local-def (cdr (assoc form venv))))
  337.        (if (and (consp local-def)
  338.             (eq (car local-def) 'macro))
  339.            (values (cdr local-def) t)
  340.            (values form nil))))
  341.     (t
  342.      (values form nil))))
  343.  
  344. (defun macroexpand (form &optional env)
  345.   "Repetitively call MACROEXPAND-1 until the form can no longer be expanded.
  346.    Returns the final resultant form, and T if it was expanded.  ENV is the
  347.    lexical environment to expand in, or NIL (the default) for the null
  348.    environment."
  349.   (labels ((frob (form expanded)
  350.          (multiple-value-bind
  351.          (new-form newly-expanded)
  352.          (macroexpand-1 form env)
  353.            (if newly-expanded
  354.            (frob new-form t)
  355.            (values new-form expanded)))))
  356.     (frob form nil)))
  357.  
  358. (defun compiler-macro-function (name &optional env)
  359.   "If NAME names a compiler-macro, returns the expansion function,
  360.    else returns NIL.  Note: if the name is shadowed in ENV by a local
  361.    definition, or declared NOTINLINE, NIL is returned.  Can be
  362.    set with SETF."
  363.   (unless (or (and env (assoc name (c::lexenv-functions env) :test #'equal))
  364.           (eq (or (and env
  365.                (cdr (assoc name (c::lexenv-inlines env)
  366.                        :key #'c::leaf-name :test #'equal)))
  367.               (info function inlinep name))
  368.           :notinline))
  369.     (values (info function compiler-macro-function name))))
  370.  
  371. (defun (setf compiler-macro-function) (function name)
  372.   (declare (type (or symbol list) name)
  373.        (type (or function null) function))
  374.   (when (eq (info function kind name) :special-form)
  375.     (error "~S names a special form." name))
  376.   (setf (info function compiler-macro-function name) function)
  377.   function)
  378.  
  379. (defun compiler-macroexpand-1 (form &optional env)
  380.   "If FORM is a function call for which a compiler-macro has been defined,
  381.    invoke the expander function using *macroexpand-hook* and return the
  382.    results and T.  Otherwise, return the original form and NIL."
  383.   (let ((fun (and (consp form) (compiler-macro-function (car form) env))))
  384.     (if fun
  385.     (let ((result (invoke-macroexpand-hook fun form env)))
  386.       (values result (not (eq result form))))
  387.     (values form nil))))
  388.  
  389. (defun compiler-macroexpand (form &optional env)
  390.   "Repetitively call COMPILER-MACROEXPAND-1 until the form can no longer be
  391.    expanded.  ENV is the lexical environment to expand in, or NIL (the
  392.    default) for the null environment."
  393.   (labels ((frob (form expanded)
  394.          (multiple-value-bind
  395.          (new-form newly-expanded)
  396.          (compiler-macroexpand-1 form env)
  397.            (if newly-expanded
  398.            (frob new-form t)
  399.            (values new-form expanded)))))
  400.     (frob form env)))
  401.  
  402.  
  403. (defun constantp (object)
  404.   "True of any Lisp object that has a constant value: types that eval to
  405.   themselves, keywords, constants, and list whose car is QUOTE."
  406.   (typecase object
  407.     (number t)
  408.     (character t)
  409.     (array t)
  410.     (symbol
  411.      (eq (info variable kind object) :constant))
  412.     (list (eq (car object) 'quote))))
  413.  
  414.  
  415. ;;; Function invocation:
  416.  
  417. (defun apply (function arg &rest args)
  418.   "Applies FUNCTION to a list of arguments produced by evaluating ARGS in
  419.   the manner of LIST*.  That is, a list is made of the values of all but the
  420.   last argument, appended to the value of the last argument, which must be a
  421.   list."
  422.   (cond ((atom args)
  423.      (apply function arg))
  424.     ((atom (cdr args))
  425.      (apply function (cons arg (car args))))
  426.     (t (do* ((a1 args a2)
  427.          (a2 (cdr args) (cdr a2)))
  428.         ((atom (cdr a2))
  429.          (rplacd a1 (car a2))
  430.          (apply function (cons arg args)))))))
  431.  
  432.  
  433. (defun funcall (function &rest arguments)
  434.   "Calls Function with the given Arguments."
  435.   (apply function arguments))
  436.  
  437.  
  438.  
  439. ;;; Multiple-Value forms:
  440.  
  441. (defun values (&rest values)
  442.   "Returns all of its arguments, in order, as values."
  443.   (values-list values))
  444.  
  445. (defun values-list (list)
  446.   "Returns all of the elements of List, in order, as values."
  447.   (values-list list))
  448.